﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;
using MetroDataApi.Models.ModelDefination;
namespace MetroDataApi.Models
{
    public class ProjectsHelper
    {

        public static List<line> GetLines(string type, string city = "上海")
        {
            using (var db = new MetroDataDataContext())
            {
                var lineList = (from w in
                                    (from l in db.Lines
                                     join p in db.Projects on
                                     l.Id equals p.LineId into gs
                                     from g in gs.DefaultIfEmpty()
                                     where g != null && g.Remark != null && g.Remark.Length > 0 && g.Status == 1 && g.ProjectType == type
                                     select new
                                     {
                                         line = l,
                                         project = g
                                     }).ToList()
                                group w by w.line
                                    into gw
                                    orderby gw.Key.Id
                                    select new line()
                                    {
                                        name = gw.Key.Name,
                                        panaroma = gw.Key.Panorama != null ? gw.Key.Panorama : "",
                                        projects = gw.Select(p =>
                                        {
                                            var extraInfo = db.MonitorProjectExtraInfo.SingleOrDefault(q => q.PrjId == p.project.PrjId);
                                            return new project()
                                                    {
                                                        name = p.project.Name,
                                                        prjId = p.project.PrjId,
                                                        lineName = gw.Key.Name,
                                                        mState = extraInfo != null ? extraInfo.PrjState : "开挖",
                                                        tunnelType = extraInfo != null ? extraInfo.TunnelType : "单圆隧道",
                                                        mConstructionCorp = extraInfo != null ? extraInfo.ConstructionCorp : "上勘院",
                                                        mPrjLevel = extraInfo != null ? extraInfo.PrjLevel : "一级",
                                                        center = JsonConvert.DeserializeObject<center>(p.project.Remark),
                                                        //monitorPoints = ProjectsHelper.GetMonitorPoints(p.project.PrjId),
                                                        pointCount = db.MonitorPointsDictionary.Count(h => h.PrjId == p.project.PrjId),
                                                        hasJsonLayer = ProjectsHelper.HasLayer(p.project.PrjId),
                                                        status = ProjectStatusHelper.GetLastestStatus(p.project.PrjId),
                                                        //mainStatusTimeList = ProjectStatusHelper.GetMainStatusGroup(p.project.PrjId),
                                                        startTime = db.MonitorPoints.Where(s => s.PrjId == p.project.PrjId).
                                                            OrderBy(s => s.DateTime.Value).
                                                            Select(s => s.DateTime.GetValueOrDefault(DateTime.Now)).
                                                            FirstOrDefault().ToString("yyyy-MM-dd")
                                                    };
                                        }).Where(g => g.pointCount > 0).ToList()
                                    }).ToList();
                return lineList;
            }


        }

        public static List<List<project>> GetProjects()
        {
            using (var db = new MetroDataDataContext())
            {

                var prjs = (from p in db.Projects
                            where p.Remark != null && p.Remark.Length > 0 && p.Status == 1
                            orderby p.LineId
                            select new project()
                            {
                                name = p.Name,
                                prjId = p.PrjId,
                                lineName = p.LineId.ToString() + "号线",
                                center = JsonConvert.DeserializeObject<center>(p.Remark)
                            }).ToList();



                foreach (var prj in prjs)
                {
                    prj.monitorPoints = ProjectsHelper.GetMonitorPoints(prj.prjId);
                    prj.hasJsonLayer = ProjectsHelper.HasLayer(prj.prjId);
                    prj.status = ProjectStatusHelper.GetLastestStatus(prj.prjId);
                    var first = db.MonitorPoints.Where(p => p.PrjId == prj.prjId).FirstOrDefault();
                    prj.startTime = first == null ? "" : first.DateTime.Value.Date.ToString("yyyy-MM-dd");
                }
                var list = from p in prjs
                           where p.monitorPoints.Count > 0
                           group p by p.lineName into g
                           select g;
                var result = new List<List<project>>();
                foreach (var l in list)
                {
                    result.Add(l.ToList());
                }
                return result;
            }

        }

        public static project GetProjectById(int prjId)
        {
            using (var db = new MetroDataDataContext())
            {
                var prj = (from p in db.Projects
                           where p.PrjId == prjId
                           select new project()
                           {
                               name = p.Name,
                               prjId = p.PrjId,
                               center = JsonConvert.DeserializeObject<center>(p.Remark)
                           }).SingleOrDefault();
                prj.hasJsonLayer = HasLayer(prjId);
                return prj;
            }
        }
        private static bool HasLayer(int prjId)
        {
            using (var db = new MetroDataDataContext())
            {
                var l = db.PrjGeoLayers.Where(p => p.PrjId == prjId).ToList();
                return l.Count > 0 ? true : false;
            }
        }

        public static List<monitorPoints> GetMonitorPoints(int prjId)
        {
            using (var db = new MetroDataDataContext())
            {
                var list = new List<monitorPoints>();
                var types = db.PrjMonitorTypes.Where(p => p.PrjId == prjId).ToList();
                foreach (var t in types)
                {
                    var monitorPts = new monitorPoints()
                    {
                        monitorType = t.MonitorType,
                        locationPoints = GetLocationPointsByType(prjId, t.MonitorType)
                    };
                    if (monitorPts.locationPoints.Count > 0)
                    {
                        list.Add(monitorPts);
                    }

                }
                return list;
            }
        }

        public static List<locationPoints> GetLocationPointsByType(int prjId, string type)
        {
            using (var db = new MetroDataDataContext())
            {
                var list = new List<locationPoints>();
                var locationPts = from p in db.MonitorPointsDictionary
                                  where p.PrjId == prjId && p.MonitorType == type
                                  orderby p.Identity ascending
                                  group p by p.Location into g
                                  select g;
                var ringPts = getRingNumbersByPrjid(prjId);
                foreach (var lpts in locationPts)
                {
                    var locationPoints = new locationPoints()
                    {
                        location = lpts.Key,
                        points =
                        (from p in lpts
                         select new point()
                         {
                             name = p.Name.Trim(),
                             ringNumber = GetRingNumber(ringPts, p.Name)
                         }).ToList() //those points have ringnumbers,Where(p => p.ringNumber != "none")
                        //-999 means failed on query matched ringnumber
                    };

                    if (type == "自动化收敛" &&
                        locationPoints.points.Where(p => p.ringNumber != "none").Count() > 0)
                    {
                        parseAutoSurveDeivcesNo(prjId, locationPoints);
                    }
                    else
                    {
                        locationPoints.isAutoSurveyPrj = false;
                    }
                    list.Add(locationPoints);
                }
                return list;
            }
        }

        private static List<PointsRingNumbers> getRingNumbersByPrjid(int prjId)
        {

            using (var db = new MetroDataDataContext())
            {
                return db.PointsRingNumbers.Where(p => p.PrjId == prjId).ToList();
            }
        }

        private static void parseAutoSurveDeivcesNo(int prjId, locationPoints locationPoints)
        {
            using (var db = new AutoSurveyDataDataContext())
            {
                var autoPrj = db.stations.Where(p => p.prjid == prjId && p.Location == locationPoints.location).SingleOrDefault();
                if (autoPrj != null)
                {
                    var stationId = autoPrj.stationid;
                    var devicesConfigs = db.ringconfig.Where(p => p.id == stationId);
                    locationPoints.autoSurveyPrjId = autoPrj.stationid.Value;
                    locationPoints.autoSurveyPrjName = autoPrj.name;
                    locationPoints.isAutoSurveyPrj = true;
                    locationPoints.points.ForEach(p =>
                    {
                        var target = devicesConfigs.SingleOrDefault(q => q.ringNumber.Value.ToString() == p.ringNumber);
                        if (target != null)
                        {
                            p.deviceNo = target.name;
                        }
                    });
                }
                else
                {
                    locationPoints.isAutoSurveyPrj = false;
                }
            }
        }

        private static string GetRingNumber(List<PointsRingNumbers> pts, string ptName)
        {
            if (pts.Count == 0) return "none";
            var xx = (from p in pts where p.PointName == ptName select p).ToList();
            if (xx.Count > 0)
            {
                return xx[0].RingNumber;
            }
            else { return "none"; }
        }




    }

}